# -*- mode: Awk; -*-  vim: set filetype=awk :
#
# This file is part of GLEE, copyright Tim Menzies 2010, 
# tim@menzies.us  
# 
# GLEE is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GLEE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GLEE.  If not, see <http://www.gnu.org/licenses/>.

BEGIN { 
		Dir     = ENVIRON["HOME"] "/tmp"
		Magic   = ":" 
		Slots   = "theSlotsOf"
		Word    = "\\w+" 
		Whites  = "[ \t]+"
		Function= "^" Whites "function"
		Class   = "[A-Z]" Word  
        Pair    = "(" Class ")" Magic "(" Word ")" 
	    Magicp  = "^" Whites ".*" Magic ".+"
		Defp    = "Each" Whites "(" Class ")" Whites "(has|have)" Whites Word 
}

FNR == 1           { Out = Dir "/" FILENAME; printf("") > Out  }
match($0,Defp,Tmp) { def(Tmp[1]); print "# " $0>>Out; next;}
$0 ~Function       { Todo=""; split("",Swaps,"") }
Todo && $0 ~ Todo  { print vars($0)  >> Out; next }
$0 ~ Magicp        { while(match($0,Pair,Tmp)) pairs(Tmp[1],Tmp[2]) }  
                   { print $0 >> Out  } 

function pairs(class,var,renames) {
	if (! (class in All ) )
		print "!!! " class " : class not known" >> "/dev/stderr";
	renames = Swaps[var] = rename(var,class,All[class])
	Todo    = add(Todo,"|","\\<"var"\\>")
	expandSlots(var,class,One[class,0])
	sub("\\<" class Magic var "\\>",renames) # #1
}
function rename(var,class,str,  i,word,out,tmp) {
	split(str,tmp,",")
	for(i in tmp)  
		out  = add(out,",",tmp[i] var);
	return out
}	
function expandSlots(var,class,n,    i,word) {
	for(i=1;i<=n;i++) {
		word = One[class,i] var
		Todo = add(Todo,"|","\\<(" word ")\\>")
		Swaps[word] = Slots var "[\"" word  "\"]"
}}
function vars(all,    before,name,after) {
	if (match(all,Todo)) {
		before = substr(all,1,RSTART-1)
		after  = substr(all,RSTART+RLENGTH)
		name   = substr(all,RSTART,RLENGTH)
		if (! (name in Swaps))
			print "!!! " name " : var not known" >> "/dev/stderr"
		return before Swaps[name] vars(after)
	} else  
		return all 
}
function o(a,s,   i) { print ""; for(i in a) print s "[" i "]=" a[i]  >> "/dev/stderr" ; }

function add(old,sep,new) {
	return old (old ? sep : "")  new
}
function def(class,    i,j,fields,tmp) {
	for(i=3;i<=NF;i=i+2)  {
		fields = $(i+1)
		if ($i == "has")  {
			split(fields,tmp,",")
			for(j in tmp) 
				One[class,++One[class,0]] = tmp[j]
			fields=Slots
		} 
		All[class] = add(All[class],",",fields)
}}
